package com.sharemarking.wa.platform.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sharemarking.wa.common.Page;
import com.sharemarking.wa.common.ResponseParams;
import com.sharemarking.wa.common.eum.OrderStateEum;
import com.sharemarking.wa.common.exception.OrgException;
import com.sharemarking.wa.common.exception.RequestException;
import com.sharemarking.wa.common.entity.*;
import com.sharemarking.wa.common.eum.OrderOperateTypeEum;

import com.sharemarking.wa.platform.dto.orderCommon.WasteListDto;
import com.sharemarking.wa.platform.dto.receiveOrderManagement.OrderInfoDto;
import com.sharemarking.wa.platform.dto.receiveOrderManagement.OrderListDto;
import com.sharemarking.wa.platform.mapper.*;
import com.sharemarking.wa.platform.service.OrderDelayQueue.OrderDelay;
import com.sharemarking.wa.platform.service.OrderDelayQueue.OrderQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.sharemarking.wa.common.SysHttpStatus.UN_M_ORG_VERIFY;


/**
 * @author dxy
 */
@Service
public class ReceiveOrderManagementService {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SecurityService ss;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private ReceiveOrderManagementMapper receiveOrderManagementMapper;
    @Autowired
    private OrgMemberMapper orgMemberMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private AddressMapper addressMapper;
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private OrderCommonMapper orderCommonMapper;
    @Autowired
    private OrderQueue orderQueue;
    @Autowired
    private GeocodingService geocodingService;
    @Autowired
    private JGPushService jgPushService;
    @Autowired
    private OrgMapper orgMapper;
    @Autowired
    private DriverVerifyMapper driverVerifyMapper;
    @Autowired
    private WasteTypeMapper wasteTypeMapper;

    public ResponseParams<?> chooseWaste() throws Exception {
        Integer memberId = ss.getCurrentUserId();
        String code = request.getParameter("code");

        if (StringUtils.isEmpty(code)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("code"));
        }

        Order order = orderMapper.selectOne(new QueryWrapper<Order>().eq("code", code));
        if (order.getType() != 0) {
            throw RequestException.create(ResponseParams.isDataError("参数错误"));
        }

        int pageIndex = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageIndex")) ? "1" : request.getParameter("pageIndex"));
        int pageSize = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageSize")) ? "10" : request.getParameter("pageSize"));

        Integer orgId = orgMemberMapper.selectOne(new QueryWrapper<OrgMember>().eq("member_id", memberId)).getOrgId();
        List<WasteListDto> list = orderCommonMapper.getReceiveOrderWasteList(order.getId(), orgId, (pageIndex - 1) * pageSize, pageSize, null);

        return ResponseParams.ok(new Page<>(list, pageIndex, pageSize, orderCommonMapper.getReceiveOrderWasteListPageTotal(order.getId(), orgId), list.size() == pageSize));
    }


    @Transactional(rollbackFor = Exception.class)
    public ResponseParams<?> acceptOrder() throws Exception {
        Integer memberId = ss.getCurrentUserId();

        //接单要求：
        //1. 经营单位必须完成企业认证（如果没有认证，跳转到企业认证页面）
        //2. 经营单位必须与产废单位存在未过期、审核通过的合作协议（提示：未找到与该产废单位的生效合作协议，请联系产废单位）

        OrgVerify isOrgVerify = receiveOrderManagementMapper.isOrgVerify(memberId);
        if (isOrgVerify == null || isOrgVerify.getExamState() != 1) {
            throw OrgException.create(ResponseParams.error(UN_M_ORG_VERIFY));
        }

        String code = request.getParameter("code");
        Integer isAgreement = receiveOrderManagementMapper.isAgreement(memberId, code);
        if (isAgreement == null || isAgreement == 0) {
            throw RequestException.create(ResponseParams.isDataError("未找到与该产废单位的生效合作协议，请联系产废单位"));
        }


        String wasteListStr = request.getParameter("wasteList");
        String addressId = request.getParameter("addressId");

        if (StringUtils.isEmpty(code)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("code"));
        }
        if (StringUtils.isEmpty(wasteListStr)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("wasteList"));
        }
        if (StringUtils.isEmpty(addressId)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("addressId"));
        }
        List<Integer> wasteList;
        try {
            wasteList = JSON.parseArray(wasteListStr, Integer.class);
        } catch (Exception e) {
            throw RequestException.create(ResponseParams.isDataError("wasteList格式错误"));
        }

        Address address = addressMapper.selectOne(new QueryWrapper<Address>().eq("id", addressId).eq("member_id", memberId));
        if (StringUtils.isEmpty(address)) {
            throw RequestException.create(ResponseParams.isDataError("地址错误"));
        }
        Order parentOrder = orderMapper.selectOne(new QueryWrapper<Order>().eq("code", code).eq("type", 0));

        //校验提交的是否符合库存
        List<Integer> receiveOrderWasteList = receiveOrderManagementMapper.getReceiveOrderWasteIdList(parentOrder.getId(), isOrgVerify.getOrgId());

        for (Integer i : wasteList) {
            if (!receiveOrderWasteList.contains(i)) {
                throw RequestException.create(ResponseParams.isDataError("呀，手慢了，废品已经被接完了"));
            }
        }


        Order newOrder = new Order();
        newOrder.setSendOrgId(parentOrder.getSendOrgId());
        newOrder.setSendOrgMemberId(parentOrder.getSendOrgMemberId());
        newOrder.setIsUrgent(parentOrder.getIsUrgent());
        newOrder.setState(OrderStateEum.UNPAID.getKey());//代付款
        newOrder.setCreateDate(new Date());
        newOrder.setReceiveOrgMemberId(memberId);
        newOrder.setReceiveOrgId(orgMemberMapper.selectOne(new QueryWrapper<OrgMember>().select("org_id").eq("member_id", memberId)).getOrgId());
        newOrder.setTransferEnd(parentOrder.getTransferEnd());
        newOrder.setTransferStart(parentOrder.getTransferStart());
        newOrder.setCarRequirement(parentOrder.getCarRequirement());
        newOrder.setParentId(parentOrder.getId());
        newOrder.setCarWeight(parentOrder.getCarWeight());
        newOrder.setType(1);
        //设置子单司机memberId和carNumber
        if (!ObjectUtils.isEmpty(parentOrder.getDriverId())) {
            newOrder.setCarId(driverVerifyMapper.selectOne(new QueryWrapper<DriverVerify>().eq("driver_id", parentOrder.getDriverId())).getId());
            newOrder.setDriverId(parentOrder.getDriverId());
            newOrder.setCarNumber(driverVerifyMapper.getCarMemberIdByMemberId(parentOrder.getDriverId()));
        }
        newOrder.setTransportOrgId(parentOrder.getTransportOrgId());

        //根据地址生成距离和运费
        //获取起始距离
        String orderStartAddress = receiveOrderManagementMapper.getOrderStartAddress(parentOrder.getId());
        String orderEndAddress = address.getProvince() + address.getCity() + address.getArea() + address.getAddress();
        Integer distance = geocodingService.getDistanceFromTwoPlaces(orderStartAddress, orderEndAddress);
        newOrder.setDistance(distance);
        //获取重量
        double weight = 0;
        double fess = 0;
        for (Integer i : wasteList) {
            OrderDetails orderDetails = orderDetailMapper.selectOne(new QueryWrapper<OrderDetails>().eq("waste_id", i).eq("order_id", parentOrder.getId()));
//            weight += orderDetails.getWeight();
            //获取废品类别单价
            double price = wasteTypeMapper.selectOne(new QueryWrapper<WasteType>().eq("name",orderDetails.getWasteTypeName())).getPrice();
            try {
                fess += parentOrder.getCarWeight()/1000 * price/100 * distance ;
            }catch (Exception e){
                throw RequestException.create(ResponseParams.isDataError("价格计算错误！"));
            }
        }
        //根据公式计算价格
//        上线正式之后，正式环境，先调成12公里内起步价250元，再加上6元一公里吧
//        Integer fess;
//        if (distance <= 12) {
//            fess = 250;
//        } else {
//            fess = (distance - 12) * 6 + 250;
//        }


        newOrder.setTransportFees((int)fess);
//        newOrder.setTransportFees(1);
        //获取最新的子订单编号
        Order childOrder = orderMapper.selectOne(new QueryWrapper<Order>().eq("parent_id", parentOrder.getId()).last("ORDER BY id DESC LIMIT 1"));
        if (childOrder == null) {//如果没有子订单
            newOrder.setCode(parentOrder.getCode() + "-1");
        } else {
            String arr[] = childOrder.getCode().split("-");
            String newChildId = String.valueOf(Integer.valueOf(arr[1]) + 1);
            newOrder.setCode(arr[0] + "-" + newChildId);
        }
        //插入数据库
        orderMapper.insert(newOrder);

        //将接单数据插入order_detail
        for (Integer i : wasteList) {
            OrderDetails orderDetails = orderDetailMapper.selectOne(new QueryWrapper<OrderDetails>().eq("waste_id", i).eq("order_id", parentOrder.getId()));

            OrderDetails newOrderDetails = new OrderDetails();
            newOrderDetails.setOrderId(newOrder.getId());
            newOrderDetails.setWasteId(i);
            newOrderDetails.setWeight(orderDetails.getWeight());
            newOrderDetails.setName(orderDetails.getName());
            newOrderDetails.setCreateDate(new Date());
            newOrderDetails.setWasteTypeName(orderDetails.getWasteTypeName());
            newOrderDetails.setParentOrderId(parentOrder.getId());
            orderDetailMapper.insert(newOrderDetails);
        }


        //将收货地址插入order_address
        OrderAddress unloadingAddress = new OrderAddress();
        unloadingAddress.setProvince(address.getProvince());
        unloadingAddress.setCity(address.getCity());
        unloadingAddress.setArea(address.getArea());
        unloadingAddress.setAddress(address.getAddress());
        unloadingAddress.setOrderId(newOrder.getId());
        unloadingAddress.setType(1);
        unloadingAddress.setCreateDate(new Date());
        orderAddressMapper.insert(unloadingAddress);

        //将装货地址再插入order_address
        OrderAddress loadingAddress = orderAddressMapper.selectOne(new QueryWrapper<OrderAddress>().eq("order_id", parentOrder.getId()).eq("type", 0));
        loadingAddress.setOrderId(newOrder.getId());
        loadingAddress.setCreateDate(new Date());
        loadingAddress.setId(null);
        orderAddressMapper.insert(loadingAddress);

        Map<String, Object> map = new HashMap<>();
        map.put("code", newOrder.getCode());

        //发送消息
        String unFinishWaste = receiveOrderManagementMapper.getRemainOrderWasteInfoStr(parentOrder.getId());
        if (unFinishWaste == null) {
            unFinishWaste = "无";
        }
        String messageStr = "您好，尾号为" + parentOrder.getCode().substring(parentOrder.getCode().length() - 10) + "的总订单已被" + orgMapper.getOrgNameById(newOrder.getReceiveOrgId()) + "接单，总订单共发布了" + receiveOrderManagementMapper.getOrderWasteInfoStr(parentOrder.getId()) +
                "，本次接单" + receiveOrderManagementMapper.getOrderWasteInfoStr(newOrder.getId()) + "，总单余下未接单" + unFinishWaste;
        jgPushService.pushTag(messageStr, parentOrder.getSendOrgMemberId());

        //将订单id缓存入延迟队列
        OrderDelay orderDelay = new OrderDelay(newOrder.getId(), 10 * 60 * 1000);//十分钟的限制
        orderQueue.getQueue().offer(orderDelay);
        return ResponseParams.ok(map);
    }


    public static String createNumber(String code) {
        StringBuilder newCode = new StringBuilder();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmm"); // 时间字符串产生方式
        String timeCode = format.format(new Date()); // 组合流水号前一部分，时间字符串，如：202002111200
        if (code != null && code.substring(0, 12).equals(timeCode.substring(0, 12))) {
            Integer codeEnd = Integer.valueOf("1" + code.substring(12, 16)) + 1;//单号+1
            timeCode = timeCode + String.valueOf(codeEnd).substring(1, 5);
        } else {
            timeCode = timeCode + "0001";
        }
        newCode.append(timeCode);

        return newCode.toString();

    }

}
